package com.lewis.request;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.ContentEncodingHttpClient;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

public class ReRouteHandler implements HttpHandler {

	@Override
	public void handle(HttpExchange exchange) throws IOException {
		URI uri = exchange.getRequestURI();
		Headers headers = exchange.getRequestHeaders();
		InputStream is = exchange.getRequestBody();
		String method = exchange.getRequestMethod();
		//list all the browser request details
		System.out.println("-------------- url: " + uri.getHost() + uri.getPath());
		
		HttpClient httpClient = new ContentEncodingHttpClient();
//		HttpHost proxy = new HttpHost("connsvr.nike.com", 8080);
//		httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
		HttpResponse response = null;
		if (method.equals("GET")){
			HttpGet httpGet = new HttpGet(uri);
			resolveHeaders(httpGet,headers);
//			System.err.println("request uri " + uri.toString());
			response = httpClient.execute(httpGet);
		}
		if (method.equals("POST")){
			HttpPost httpPost = new HttpPost(uri);
			resolveHeaders(httpPost,headers);
			response = httpClient.execute(httpPost);	
		}
		

        Header[] resHeaders = response.getAllHeaders();
        exchange.getResponseHeaders().putAll(resolveResponseHeader(resHeaders));
        InputStream resStream = response.getEntity().getContent();
        byte[] bytes = IOUtils.toByteArray(resStream);
        exchange.sendResponseHeaders(response.getStatusLine().getStatusCode(),bytes.length);
        OutputStream os = exchange.getResponseBody();
        os.write(bytes);
        os.close();
//        StringWriter writer = new StringWriter();
//        IOUtils.copy(is, writer, "utf-8");
//        String theString = writer.toString();
//        System.out.println("request body: "+ theString);
//        exchange.sendResponseHeaders(200,theString.length());
//      OutputStream os = exchange.getResponseBody();
//      os.write(theString.getBytes());
//      os.close();
	}

	private Map<? extends String, ? extends List<String>> resolveResponseHeader(
			Header[] resHeaders) {
		Map<String,List<String>> map = new HashMap<String, List<String>>();
		for(Header header:resHeaders){
			System.out.println("response header name: "+ header.getName() + "  value " + header.getValue());
			List<String> list = new ArrayList<String>();
			list.add(header.getValue());
			map.put(header.getName(), list);
		}
		return map;
	}

	private void resolveHeaders(HttpRequestBase http,Headers headers) {
		for(Map.Entry<String, List<String>> entry : headers.entrySet()){
			List<String> list = entry.getValue();
			if (entry.getKey().equals("User-agent")){
//				System.out.println("adding header to the http request:  name: "+ entry.getKey() + "  value "+list.get(0));
				http.addHeader(entry.getKey(), "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0)");
				http.addHeader(entry.getKey(), "Gecko/20100101");
				http.addHeader(entry.getKey(), "Firefox/14.0.1");
			} 
			else if(entry.getKey().equals("Accept-encoding")){
				String[] multi = list.get(0).split(",");
				for(String string:multi){
//					System.out.println("adding header to the http request:  name: "+ entry.getKey() + "  value "+string.trim());
					http.addHeader(entry.getKey(), string.trim());
				}
			}
			else if (list.get(0).contains(";")){
				System.out.println("Multiple message-header fields");
				String[] multi = list.get(0).split(";");
				for(String string:multi){
//					System.out.println("adding header to the http request:  name: "+ entry.getKey() + "  value "+string.trim());
					http.addHeader(entry.getKey(), string.trim());
				}
			} else{
//				System.out.println("adding header to the http request:  name: "+ entry.getKey() + "  value "+list.get(0));
				http.addHeader(entry.getKey(), list.get(0));
			}
		}
		
	}

}
